package com.coupon.template.service.impl;

import com.coupon.common.constant.Constants;
import com.coupon.template.dao.CouponTemplateDao;
import com.coupon.template.entity.CouponTemplate;
import com.coupon.template.service.AsyncService;
import com.google.common.base.Stopwatch;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @author 王哲
 * @Contact 1121586359@qq.com
 * @ClassName AsyncServiceImpl.java
 * @create 2023年06月25日 下午3:35
 * @Description 异步服务接口实现类
 * @Version V1.0
 */
@Slf4j
@Service
public class AsyncServiceImpl implements AsyncService {

    @Autowired
    private CouponTemplateDao templateDao;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 根据模板异步创建优惠券码
     * @param template {@link CouponTemplate} 优惠券模板实体
     */
    @Override
    @Async("getAsyncExecutor")
    public void asyncConstructCouponByTemplate(CouponTemplate template) {
        Stopwatch started = Stopwatch.createStarted();

        Set<String> couponCodes = buildCouponCode(template);

        String redisKey = String.format("%s%s",
                Constants.RedisPrefix.COUPON_TEMPLATE, template.getId().toString());

        log.info("Push CouponCode To Redis: {}",
                stringRedisTemplate.opsForList().rightPushAll(redisKey, couponCodes));

        template.setAvailable(true);

        templateDao.save(template);

        started.stop();
        log.info("Construct CouponCode By Template Cost: {}ms",
                started.elapsed(TimeUnit.MILLISECONDS));

        // TODO 发送短信或者邮件通知优惠券模板已经可用
        log.info("CouponTemplate({}) Is Available!", template.getId());
    }
    // 构造优惠券码 优惠券码对应于每一张优惠券，18位
    // 前四位：产品线 + 类型
    // 中间六位：日期随机（190101）
    // 后八位：0-9随机数构成
    private Set<String> buildCouponCode(CouponTemplate template) {
        Stopwatch started = Stopwatch.createStarted();

        Set<String> result = new HashSet<>(template.getCount());
        // 前四位
        String prefix4 = template.getProductLine().getCode().toString()
                + template.getCategory().getCode();
        // 中间六位
        String date = new SimpleDateFormat("yyMMdd")
                .format(template.getCreateTime());
        // 后八位
        for (int i = 0; i != template.getCount(); ++i) {
            result.add(prefix4 + buildCouponCodeSuffix14(date));
        }

        while (result.size() < template.getCount()) {
            result.add(prefix4 + buildCouponCodeSuffix14(date));
        }

        assert result.size() == template.getCount();

        started.stop();
        log.info("Build Coupon Code Cost: {}ms",
                started.elapsed(TimeUnit.MILLISECONDS));

        return result;
    }

    /**
     * 构造优惠券码的后14位
     * @param date
     * @return
     */
    private String buildCouponCodeSuffix14(String date) {
        String random = RandomStringUtils.random(8, false, true);
        if (random.startsWith("0")) {
            return buildCouponCodeSuffix14(date);
        }
        return date + random;
    }

}
